package cz.hanis.android.geography;

import java.util.ArrayList;
import java.util.List;

import com.actionbarsherlock.app.SherlockActivity;
import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;

import cz.hanis.android.geography.activities.TestResultActivity;

import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.WindowManager;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

public abstract class TestActivity extends SherlockActivity {

	private static final String PROGRESS_STATUS_KEY = "psk";
	private static final String ROUND_KEY = "rk";
	private static final String SCORE_KEY = "sk";
	private static final String TEST_SPEC_KEY = "tsk";
	private static final String LIVES_KEY = "lk";
	
	
	
	public static final String CORRECT_POSITION_KEY = "cpk";
	public static final String QUESTION_KEY = "cnk";
	public static final String ANSWER_LIST_KEY = "alk";

	public static final String TAG_TEST_PROGRESS_THREAD = "TEST PROGRESS THREAD";

	protected static final int ANSWERE_TIMED_OUT = -1;
	protected static final int ANSWERE_CORRECT = -3;
	protected static final int ANSWERE_INCORRECT = -4;
	protected static final int ANSWERE_NONE = -2;

	private GeographyApplication app;
	private int progressStatus;
	private Thread progressThread;
	private int delay;
	private boolean answering = false;

	private TestSpecification testSpec;
	private int round;
	private int score;

	private TextView tvQuestion;
	private ProgressBar pbProgressBar;

	private TextView tvScore;
	private TextView tvHighscore;
	private LinearLayout llLives;
	private List<View> liveList;

	private int lives;

	private CountryTools tools;

	private List<View> answerViews;
	private View questionView;

	private Animation incorrectAnimation;
	private Animation correctAnimation;

	// private AdView adView;

	private boolean active;
	
	private Handler progressHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			progressStatus++;
			Log.d("THREADS", "ps: " + progressStatus + ", tm: " + msg.toString());
			if (progressStatus > 99) {
				answer(TestActivity.ANSWERE_TIMED_OUT);
			} else {
				pbProgressBar.setProgress(progressStatus);
			}
		}
	};
		

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.test_layout);
		getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		incorrectAnimation = AnimationUtils.loadAnimation(this,
				R.anim.incorrect_flag);
		incorrectAnimation.setRepeatCount(6);
		correctAnimation = AnimationUtils.loadAnimation(this,
				R.anim.correct_flag);
		app = (GeographyApplication) getApplication();
		tools = app.getCountryTool();

		answerViews = new ArrayList<View>();
		

		tvHighscore = (TextView) findViewById(R.id.tv_test_status_highscore);
		tvScore = (TextView) findViewById(R.id.tv_test_status_score);
		llLives = (LinearLayout) findViewById(R.id.ll_test_status_lives);

		pbProgressBar = (ProgressBar) findViewById(R.id.pb_test_progress);
		tvQuestion = (TextView) findViewById(R.id.tv_test_question);

		init(savedInstanceState);
	}

	private void init(Bundle savedInstanceState) {

		if (savedInstanceState == null) {
			score = 0;
			round = 0;
			lives = 3;
			testSpec = (TestSpecification) getIntent().getParcelableExtra(
					TestSpecification.KEY);
		} else {
			score = savedInstanceState.getInt(SCORE_KEY);
			round = savedInstanceState.getInt(ROUND_KEY);
			lives = savedInstanceState.getInt(LIVES_KEY);
			testSpec = (TestSpecification) savedInstanceState
					.getParcelable(TEST_SPEC_KEY);
			progressStatus = savedInstanceState.getInt(PROGRESS_STATUS_KEY);
		}

		delay = 30;
		int highscore = GeographyApplication.getInstance()
				.getHighScoreHandler().getHighScore(testSpec);
		tvHighscore.setText(String.valueOf(highscore));
		tvScore.setText(String.valueOf(score));
		liveList = new ArrayList<View>();
		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		for (int i = 0; i < lives; i++) {
			View live = inflater.inflate(R.layout.live, null);
			llLives.addView(live);
			liveList.add(live);
		}
	}
	
	protected void setListeners() {
		int i=0;
		for(View view : getAnswerViews()) {
			final int index = i++;
			view.setOnClickListener(new View.OnClickListener() {
				@Override
				public void onClick(View v) {
					answer(index);
				}
			});
		}
	}
	

	@Override
	public void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		outState.putInt(PROGRESS_STATUS_KEY, progressStatus);
		outState.putInt(ROUND_KEY, round);
		outState.putInt(SCORE_KEY, score);
		outState.putInt(LIVES_KEY, lives);
		outState.putParcelable(TEST_SPEC_KEY, testSpec);
	}

	protected void setBackgroudButton(int number, int background) {
		View view = getAnswerViews().get(number);
		int bottom = view.getPaddingBottom();
		int top = view.getPaddingTop();
		int right = view.getPaddingRight();
		int left = view.getPaddingLeft();
		view.setBackgroundResource(background);
		view.setPadding(left, top, right, bottom);
	}

	protected void setQuestionView(View questionView) {
		this.questionView = questionView;
	}

	protected View getQuestionView() {
		return questionView;
	}

	protected GeographyApplication getGeogrephyApplication() {
		return app;
	}

	protected CountryTools getTools() {
		return tools;
	}

	private void onCorrect() {
		questionView.startAnimation(correctAnimation);
		score++;
		tvScore.setText(String.valueOf(score));
	}

	private void onIncorrect() {
		questionView.startAnimation(incorrectAnimation);
		lives--;
		if (lives < 1) {
			finish();
		} else {
			liveList.get(lives).setVisibility(View.INVISIBLE);
		}
	}

	protected void setQuestion(String question) {
		tvQuestion.setText(question);
	}

	protected void setTestLayout(int layout) {
		LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
		View child = inflater.inflate(layout, null);
		LinearLayout root = (LinearLayout) findViewById(R.id.ll_test);
		root.addView(child);
	}

	public int getRound() {
		return round;
	}

	public void setRound(int round) {
		this.round = round;
	}

	public void newRound() {
		progressStatus = 0;		
		round++;
		enableAnswerViews();
		onNewRound();
		if(round > 1) {
			startCounting();
		}
		answering = true;
	}

	public void restoreRound() {
		enableAnswerViews();
		onRestoreRound();
		// startCounting();
		answering = true;
	}

	public void finish() {
		active = false;
		answering = false;
		removeCallbacks();
		Intent intent = new Intent(TestActivity.this, TestResultActivity.class);
		intent.putExtra(TestSpecification.KEY, testSpec);
		intent.putExtra(TestResultActivity.CORRECT_ANSWER_KEY, score);
		startActivity(intent);
		super.finish();
	}

	private void startCounting() {
		removeCallbacks();
		progressThread = new Thread(new Runnable() {
			@Override
			public void run() {
				final int roundStarted = round;
				while (answering && roundStarted == round
						&& progressStatus < 100) {
					Log.d("THREADS", progressThread.toString());
					try {
						progressHandler.sendMessage(progressHandler
								.obtainMessage());
						Thread.sleep(getDelay() * 10);
					} catch (Throwable t) {
						t.printStackTrace();
						Log.d(TestActivity.TAG_TEST_PROGRESS_THREAD,
								t.getMessage());
					}
				}
			}
		});

		progressThread.start();
	}

	protected void answer(int answer) {
		answering = false;
		disableAnswerViews();
		int answerType = onAnswer(answer);
		progressHandler.removeCallbacks(progressThread);

		if (answerType == TestActivity.ANSWERE_CORRECT) {
			onCorrect();
		} else {
			onIncorrect();
		}
		if (lives > 0) {
			Handler handler = new Handler();
			handler.postDelayed(new Runnable() {
				public void run() {
					if(active) {
						newRound();
					}
				}
			}, 1000);
		}
	}

	private void removeCallbacks() {
		if (progressThread != null && progressHandler != null) {
			progressHandler.removeCallbacks(progressThread);
		}
	}

	protected void answer() {
		answer(TestActivity.ANSWERE_NONE);
	}

	protected abstract void onNewRound();

	protected abstract void onRestoreRound();

	protected abstract int onAnswer(int answer);

	public int getDelay() {
		return delay;
	}

	public void setDelay(int delay) {
		this.delay = delay;
	}

	public boolean isAnswering() {
		return answering;
	}

	public void setAnswering(boolean answering) {
		this.answering = answering;
	}

	public TestSpecification getTest() {
		return testSpec;
	}

	public void setTest(TestSpecification test) {
		this.testSpec = test;
	}

	protected void enableAnswerViews() {
		for (View view : answerViews) {
			view.setEnabled(true);
		}
	}

	protected void disableAnswerViews() {
		for (View view : answerViews) {
			view.setEnabled(false);
		}
	}

	public List<View> getAnswerViews() {
		return answerViews;
	}

	public void addAnswerView(View view) {
		answerViews.add(view);
	}

	public int getNumberOfAnswers() {
		return answerViews.size();
	}

	@Override
	protected void onPause() {
		super.onPause();
		active = false;
		answering = false;
	}

	@Override
	protected void onResume() {
		answering = true;
		active = true;		
		if(progressStatus < 100) {			
			startCounting();
		} else {
			newRound();
		}
		super.onResume();
	}

}
